import LetterSpacing from './letter-spacing.svg';
import LineHeight from './line-height.svg';
import Weight from './weight.svg';
import {ScaleTable, TabularFigureTable} from './tables';

<Meta title="Core/Typography" />

# Typography

We've built Sentry's type system around Rubik - a playful open-source typeface. For code and code-like elements, we use Roboto Mono.

---

## Type scale

Type scales are hierarchical type systems consisting of style definitions for common elements, such as Heading 1, Heading 2, Paragraph, and Button/Label.

**Sentry's type scale is based on the Rubik typeface. The root font size is 16px (1rem = 16px).**

<ScaleTable />

---

## Styling

The type scale above should cover a large majority of use cases. However, if an element requires a custom style outside of the type scale, make sure to follow the rules below.

### Size

**Use values from the type scale above.** Be mindful of the type hierarchy. If the element has low importance, use a smaller size.

**Always define font sizes with the `rem` unit.**

### Weight

<img
  src={Weight}
  alt="Examples of font weights for common text elements"
  className="with-border"
/>

- **Use Medium (600)** for headings, button labels, and elements that need to stand out from the rest of the user interface, like table headers

- **Use Regular (400)** for all other elements

### Line height

<img
  src={LineHeight}
  alt="Examples of line heights for common text elements"
  className="with-border"
/>

- **Use 1.4** for body text (content that can wrap to multiple lines)
- **Use 1.2** for headings and short, single-line text like table headers and input fields
- **Use 1** for text labels with immediate bounding boxes, like buttons, pills, and badges

### Letter spacing

<img
  src={LetterSpacing}
  alt="Visualization of letter spacing in headings and small text"
  className="with-border"
/>

- **Reduce letter spacing for headings**. This makes them look more condensed, thereby reinforcing their high order in the type hierarchy. Refer to the type scale above for how much to reduce.

- **Increase letter spacing (+0.02rem) in text elements that are smaller than 16px**, with the exception of code and code-like elements. This makes them easier to read.

---

## Code

**Use Roboto Mono in Regular (400)** for code and code-like elements, like search tokens.

**Set the line height based on the context:**

- **For multi-line code**, use 1.6
- **For single-line code elements**, like search tokens, use the same line height as that of the text surrounding the token

---

## External links

External links lead users to pages outside the application. Examples include links to Sentry's blog/marketing pages, terms of service, third-party documentation,…

The following styling rules apply to external links only. Internal links, on the other hand, can have more flexible styles, based on their behavior and context.

### In a sentence

When a link appears inside a longer sentence…

<Sample>
  …like this&nbsp;
  <a href="" target="_blank">
    little link
  </a>
</Sample>

- Use <ColorChip value="blue300" /> as the text color
- Add a solid underline in <ColorChip value="blue100" />
- Don't include any preceding articles (a, the, this, our) in the linked text, for example:
  - Yay: the <a href="" target="_blank">Church of the Flying Spaghetti Monster</a>
  - Nay: <a href="" target="_blank">the Church of the Flying Spaghetti Monster</a>
- On hover:
  - Use a pointer cursor – `cursor: pointer`
  - Change the underline color to <ColorChip value="blue200" />

```js label=Styled_Components
styled('a')`
  color: ${p => p.theme.blue300};
  text-decoration: underline;
  text-decoration-color: ${p => p.theme.blue100};
  cursor: pointer;

  &:hover {
    text-decoration-color: ${p => p.theme.blue200};
  }
`;
```

### Standalone

When a link appears on its own and the user likely knows that it's a link given the context, like in a footer:

<Sample>
  <a href="https://sentry.io/privacy/" target="_blank" className="gray-link">
    Privacy Policy
  </a>
  <br />
  <a href="https://sentry.io/terms/" target="_blank" className="gray-link">
    Terms of Use
  </a>
</Sample>

- Use <ColorChip value="gray500" />, <ColorChip value="gray400" />, or <ColorChip value="gray300" />, depending on the context
- Don't add any underline
- On hover:
  - Use a pointer cursor – `cursor: pointer`
  - Add a solid underline in <ColorChip value="gray200" />

```js label=Styled_Components
/* Link color is flexible, choose
between Gray 500, 400, and 300. */
styled('a')`
  color: ${p => p.theme.gray500};
  text-decoration: none;
  cursor: pointer;

  &:hover {
    text-decoration: underline;
    text-decoration-color: ${p => p.theme.gray200};
  }
`;
```

---

## Lists

### Unordered

**Use filled and hollow circles as bullets points:**

<Sample>
  <ul>
    <li>
      Camelus
      <ul>
        <li>Bactrian camel</li>
        <li>Dromedary</li>
      </ul>
    </li>
    <li>
      Lama
      <ul>
        <li>Llama</li>
        <li>Alpaca</li>
      </ul>
    </li>
  </ul>
</Sample>

```css label=CSS
/* First-level items */
ul > li {
  list-style-type: disc;
}

/* Second-level items */
ul > ul > li {
  list-style-type: circle;
}
```

**Don't add full stops (.) to the end of each item**, unless the item contains multiple sentences.

**Avoid using custom symbols and icons as bullet characters**, as they usually look out of place and distract from the main text content.

### Ordered

**Use Arabic numerals and lowercase letters as counters:**

<Sample>
  <ol>
    <li>
      Camelus
      <ol>
        <li>Bactrian camel</li>
        <li>Dromedary</li>
      </ol>
    </li>
    <li>
      Lama
      <ol>
        <li>Llama</li>
        <li>Alpaca</li>
      </ol>
    </li>
  </ol>
</Sample>

```css label=CSS
/* First-level items */
ul > li {
  list-style-type: decimal;
}

/* Second-level items */
ul > ul > li {
  list-style-type: lower-alpha;
}
```

**Avoid using custom symbols and icons as counters**.

---

## OpenType features

Rubik supports a few useful [OpenType font features](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/OpenType_fonts_guide). These features, or variants, are alternative characters that, when used in the right places, can help improve the reading experience.

### Tabular figures

By default, Rubik uses proportional figures. This works well in most cases. However, for large tables with a lot of numbers, tabular figures would be a better choice, thanks to their consistent width and more legible design.

<TabularFigureTable />

**Use tabular figures in tables, but limit their use to numeric columns only.** For non-numeric columns and other non-tabular elements, use the default proportional settings.

```css label=CSS
/* Add this to numeric columns */
font-variant-numeric: tabular-nums;
```

### Ligatures

Ligatures are special glyphs that replace two or more glyphs in order to better connect them. Common ligature replacements include ff, fi, fl, and ffi.

Without ligatures, the characters are all separate:

<h1 style={{fontFeatureSettings: "'liga' 0", margin: 0}}>ff, fi, fl</h1>

With ligatures, the characters are connected into a single glyph:

<h1 style={{margin: 0}}>ff, fi, fl</h1>

**Use ligatures across the whole user interface.**

```css label=CSS
/* Add this to the root element */
font-feature-settings: 'liga';
```

### Fractions

Rubik also contains special formatting for fractions. Without this formatting, numbers in fractions are just rendered as separate characters:

<h1 style={{margin: 0}}>1/12</h1>

Fractional formatting shrinks the numbers and connects them with a diagonal slash, forming a proportional, condensed visual block:

<h1 style={{fontFeatureSettings: "'frac'", margin: 0}}>1/12</h1>

**Use fractional formatting whenever possible.**

```css label=CSS
/* Be careful: this changes the appearance of normal,
non-fractional numbers, so only apply it to specific
text elements with fractions inside. */
font-feature-settings: 'frac';
```
